<?php
global $CFG;
require_once($CFG->dirroot . '/blocks/formal_langs/langs_src/tools/JLexPHP/jlex.php');
require_once($CFG->dirroot . '/blocks/formal_langs/tokens_base.php');
require_once($CFG->dirroot . '/blocks/formal_langs/langs_code/predefined/json_parser.php');


class json_lexer extends JLexBase  {
	const YY_BUFFER_SIZE = 512;
	const YY_F = -1;
	const YY_NO_STATE = -1;
	const YY_NOT_ACCEPT = 0;
	const YY_START = 1;
	const YY_END = 2;
	const YY_NO_ANCHOR = 4;
	const YY_BOL = 128;
	var $YY_EOF = 129;

    private $token_count = 0;
    public $errors = array();
    // buffer for accumulating string
    private $string_buffer;
    // begin and end line for position
    private $string_pos_bl, $string_pos_el;
    // begin and end column for position
    private $string_pos_bc, $string_pos_ec;
    private function return_token($type, $value, $desc) {
        // create token object
        $res = new block_formal_langs_token_base(NULL, $type, $value, $this->return_pos(), $this->token_count);
        $res->set_description($desc);
        // increase token count
        $this->token_count++;
        return $res;
    }
    private function return_pos() {
        $begin_line = $this->yyline;
        $begin_col = $this->yycol;
        if(strpos($this->yytext(), '\n')) {
            $lines = explode("\n", $this->yytext());
            $num_lines = count($lines);
            $end_line = $begin_line + $num_lines - 1;
            $end_col = strlen($lines[$num_lines -1]);
        } else {
            $end_line = $begin_line;
            $end_col = $begin_col + strlen($this->yytext());
        }
        $res = new block_formal_langs_node_position($begin_line, $end_line, $begin_col, $end_col);
        return $res;
    }
    private function return_string() {
        // create position object
        $pos = new block_formal_langs_node_position($this->string_pos_bl, $this->string_pos_el, $this->string_pos_bc, $this->string_pos_ec);
        // create token object
        $res = new block_formal_langs_token_base(NULL, json_yyParser::STRING, $this->string_buffer, $pos, $this->token_count);
        $res->set_description("STRING");
        $this->token_count++;
        $this->string_buffer = '';
        return $res;
    }
	protected $yy_count_chars = true;
	protected $yy_count_lines = true;

	function __construct($stream) {
		parent::__construct($stream);
		$this->yy_lexical_state = self::YYINITIAL;
	}

	const STRING = 1;
	const YYINITIAL = 0;
	static $yy_state_dtrans = array(
		0,
		42
	);
	static $yy_acpt = array(
		/* 0 */ self::YY_NOT_ACCEPT,
		/* 1 */ self::YY_NO_ANCHOR,
		/* 2 */ self::YY_NO_ANCHOR,
		/* 3 */ self::YY_NO_ANCHOR,
		/* 4 */ self::YY_NO_ANCHOR,
		/* 5 */ self::YY_NO_ANCHOR,
		/* 6 */ self::YY_NO_ANCHOR,
		/* 7 */ self::YY_NO_ANCHOR,
		/* 8 */ self::YY_NO_ANCHOR,
		/* 9 */ self::YY_NO_ANCHOR,
		/* 10 */ self::YY_NO_ANCHOR,
		/* 11 */ self::YY_NO_ANCHOR,
		/* 12 */ self::YY_NO_ANCHOR,
		/* 13 */ self::YY_NO_ANCHOR,
		/* 14 */ self::YY_NO_ANCHOR,
		/* 15 */ self::YY_NO_ANCHOR,
		/* 16 */ self::YY_NO_ANCHOR,
		/* 17 */ self::YY_NO_ANCHOR,
		/* 18 */ self::YY_NO_ANCHOR,
		/* 19 */ self::YY_NO_ANCHOR,
		/* 20 */ self::YY_NO_ANCHOR,
		/* 21 */ self::YY_NO_ANCHOR,
		/* 22 */ self::YY_NO_ANCHOR,
		/* 23 */ self::YY_NO_ANCHOR,
		/* 24 */ self::YY_NO_ANCHOR,
		/* 25 */ self::YY_NO_ANCHOR,
		/* 26 */ self::YY_NO_ANCHOR,
		/* 27 */ self::YY_NO_ANCHOR,
		/* 28 */ self::YY_NOT_ACCEPT,
		/* 29 */ self::YY_NO_ANCHOR,
		/* 30 */ self::YY_NO_ANCHOR,
		/* 31 */ self::YY_NOT_ACCEPT,
		/* 32 */ self::YY_NO_ANCHOR,
		/* 33 */ self::YY_NOT_ACCEPT,
		/* 34 */ self::YY_NO_ANCHOR,
		/* 35 */ self::YY_NOT_ACCEPT,
		/* 36 */ self::YY_NO_ANCHOR,
		/* 37 */ self::YY_NOT_ACCEPT,
		/* 38 */ self::YY_NOT_ACCEPT,
		/* 39 */ self::YY_NOT_ACCEPT,
		/* 40 */ self::YY_NOT_ACCEPT,
		/* 41 */ self::YY_NOT_ACCEPT,
		/* 42 */ self::YY_NOT_ACCEPT,
		/* 43 */ self::YY_NOT_ACCEPT,
		/* 44 */ self::YY_NOT_ACCEPT,
		/* 45 */ self::YY_NOT_ACCEPT,
		/* 46 */ self::YY_NOT_ACCEPT,
		/* 47 */ self::YY_NOT_ACCEPT
	);
		static $yy_cmap = array(
 2, 2, 2, 2, 2, 2, 2, 2, 2, 27, 27, 2, 2, 27, 2, 2, 2, 2, 2, 2,
 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 27, 2, 1, 2, 2, 2, 2, 2,
 2, 2, 2, 16, 26, 12, 14, 4, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 25, 2,
 2, 2, 2, 2, 2, 11, 11, 11, 11, 15, 11, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 23, 3, 24, 2, 2, 2, 18, 5, 11,
 11, 17, 6, 2, 2, 2, 2, 2, 19, 2, 8, 2, 2, 2, 7, 20, 9, 10, 2, 2,
 2, 2, 2, 21, 2, 22, 2, 2, 0, 0,);

		static $yy_rmap = array(
 0, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 4, 1, 1, 1, 1, 5, 6, 1,
 1, 1, 1, 1, 1, 1, 1, 1, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
 9, 19, 20, 21, 22, 23, 24, 25,);

		static $yy_nxt = array(
array(
 1, 2, 3, 3, 3, 3, 29, 3, 32, 34, 3, 3, 36, 4, 3, 3, 3, 3, 3, 3,
 3, 5, 6, 7, 8, 9, 10, 11,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 33, 35, -1, 35, -1, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 -1, -1, -1, -1, -1, -1, -1, 11,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, -1, 35, -1, 35, -1, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, 17, -1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
 17, 17, 17, 17, 17, 17, 17, 17,
),
array(
 -1, 19, -1, 20, 21, 22, 23, 24, 25, 26, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 37,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 28, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30, -1, -1, -1, -1, -1, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 45, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, -1, -1, -1, -1, -1, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, 31, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, 30, -1, -1, 40, -1, -1, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 41, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 13,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 14, -1, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 1, 16, 17, 18, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
 17, 17, 17, 17, 17, 17, 17, 17,
),
array(
 -1, -1, -1, -1, -1, 47, 47, -1, -1, -1, -1, 47, -1, 47, -1, 47, -1, 47, 47, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, 27, 27, -1, -1, -1, -1, 27, -1, 27, -1, 27, -1, 27, 27, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, 44, 44, -1, -1, -1, -1, 44, -1, 44, -1, 44, -1, 44, 44, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
array(
 -1, -1, -1, -1, -1, 46, 46, -1, -1, -1, -1, 46, -1, 46, -1, 46, -1, 46, 46, -1,
 -1, -1, -1, -1, -1, -1, -1, -1,
),
);

	public function /*Yytoken*/ next_token ()
 {
		$yy_anchor = self::YY_NO_ANCHOR;
		$yy_state = self::$yy_state_dtrans[$this->yy_lexical_state];
		$yy_next_state = self::YY_NO_STATE;
		$yy_last_accept_state = self::YY_NO_STATE;
		$yy_initial = true;

		$this->yy_mark_start();
		$yy_this_accept = self::$yy_acpt[$yy_state];
		if (self::YY_NOT_ACCEPT != $yy_this_accept) {
			$yy_last_accept_state = $yy_state;
			$this->yy_mark_end();
		}
		while (true) {
			if ($yy_initial && $this->yy_at_bol) $yy_lookahead = self::YY_BOL;
			else $yy_lookahead = $this->yy_advance();
			$yy_next_state = self::$yy_nxt[self::$yy_rmap[$yy_state]][self::$yy_cmap[$yy_lookahead]];
			if ($this->YY_EOF == $yy_lookahead && true == $yy_initial) {
				return null;
			}
			if (self::YY_F != $yy_next_state) {
				$yy_state = $yy_next_state;
				$yy_initial = false;
				$yy_this_accept = self::$yy_acpt[$yy_state];
				if (self::YY_NOT_ACCEPT != $yy_this_accept) {
					$yy_last_accept_state = $yy_state;
					$this->yy_mark_end();
				}
			}
			else {
				if (self::YY_NO_STATE == $yy_last_accept_state) {
					throw new Exception("Lexical Error: Unmatched Input.");
				}
				else {
					$yy_anchor = self::$yy_acpt[$yy_last_accept_state];
					if (0 != (self::YY_END & $yy_anchor)) {
						$this->yy_move_end();
					}
					$this->yy_to_mark();
					switch ($yy_last_accept_state) {
						case 1:
							
						case -2:
							break;
						case 2:
							{
    $this->yybegin(self::STRING);
    $this->string_buffer = '';
    $this->string_pos_bl = $this->yyline;
    $this->string_pos_bc = $this->yycol;
 }
						case -3:
							break;
						case 3:
							{ /* process bad input */
    $error = array();
    $error['line'] = $this->yyline;
    $error['column'] = $this->yycol;
    $error['input'] = $this->yytext();
    $this->errors[] = $error;
}
						case -4:
							break;
						case 4:
							{ return $this->return_token(json_yyParser::INT,     $this->yytext(), "INT"); }
						case -5:
							break;
						case 5:
							{ return $this->return_token(json_yyParser::LBRACE,  $this->yytext(), "LBRACE"); }
						case -6:
							break;
						case 6:
							{ return $this->return_token(json_yyParser::RBRACE,  $this->yytext(), "RBRACE"); }
						case -7:
							break;
						case 7:
							{ return $this->return_token(json_yyParser::LSBRACE, $this->yytext(), "LSBRACE"); }
						case -8:
							break;
						case 8:
							{ return $this->return_token(json_yyParser::RSBRACE, $this->yytext(), "RSBRACE"); }
						case -9:
							break;
						case 9:
							{ return $this->return_token(json_yyParser::COLON,   $this->yytext(), "COLON"); }
						case -10:
							break;
						case 10:
							{ return $this->return_token(json_yyParser::COMMA,   $this->yytext(), "COMMA"); }
						case -11:
							break;
						case 11:
							{}
						case -12:
							break;
						case 12:
							{ return $this->return_token(json_yyParser::DOUBLE,  $this->yytext(), "DOUBLE"); }
						case -13:
							break;
						case 13:
							{ return $this->return_token(json_yyParser::NULL,    $this->yytext(), "NULL"); }
						case -14:
							break;
						case 14:
							{ return $this->return_token(json_yyParser::BOOLEAN, $this->yytext(), "BOOLEAN"); }
						case -15:
							break;
						case 15:
							{ return $this->return_token(json_yyParser::BOOLEAN, $this->yytext(), "BOOLEAN"); }
						case -16:
							break;
						case 16:
							{
    $this->string_pos_el = $this->yyline;
    $this->string_pos_ec = $this->yycol;
    $this->yybegin(self::YYINITIAL);
    return $this->return_string();
 }
						case -17:
							break;
						case 17:
							{ $this->string_buffer .= $this->yytext(); }
						case -18:
							break;
						case 18:
							{ $this->string_buffer .= "\\"; }
						case -19:
							break;
						case 19:
							{ $this->string_buffer .= "\""; }
						case -20:
							break;
						case 20:
							{ $this->string_buffer .= "\\"; }
						case -21:
							break;
						case 21:
							{ $this->string_buffer .= "/"; }
						case -22:
							break;
						case 22:
							{ $this->string_buffer .= "\b"; }
						case -23:
							break;
						case 23:
							{ $this->string_buffer .= "\f"; }
						case -24:
							break;
						case 24:
							{ $this->string_buffer .= "\r"; }
						case -25:
							break;
						case 25:
							{ $this->string_buffer .= "\n"; }
						case -26:
							break;
						case 26:
							{ $this->string_buffer .= "\t"; }
						case -27:
							break;
						case 27:
							{
    $sub = substr($this->yytext(), 2);
    $num = intval($sub, 16);
    $this->string_buffer .= chr($num);
 }
						case -28:
							break;
						case 29:
							{ /* process bad input */
    $error = array();
    $error['line'] = $this->yyline;
    $error['column'] = $this->yycol;
    $error['input'] = $this->yytext();
    $this->errors[] = $error;
}
						case -29:
							break;
						case 30:
							{ return $this->return_token(json_yyParser::DOUBLE,  $this->yytext(), "DOUBLE"); }
						case -30:
							break;
						case 32:
							{ /* process bad input */
    $error = array();
    $error['line'] = $this->yyline;
    $error['column'] = $this->yycol;
    $error['input'] = $this->yytext();
    $this->errors[] = $error;
}
						case -31:
							break;
						case 34:
							{ /* process bad input */
    $error = array();
    $error['line'] = $this->yyline;
    $error['column'] = $this->yycol;
    $error['input'] = $this->yytext();
    $this->errors[] = $error;
}
						case -32:
							break;
						case 36:
							{ /* process bad input */
    $error = array();
    $error['line'] = $this->yyline;
    $error['column'] = $this->yycol;
    $error['input'] = $this->yytext();
    $this->errors[] = $error;
}
						case -33:
							break;
						default:
						$this->yy_error('INTERNAL',false);
					case -1:
					}
					$yy_initial = true;
					$yy_state = self::$yy_state_dtrans[$this->yy_lexical_state];
					$yy_next_state = self::YY_NO_STATE;
					$yy_last_accept_state = self::YY_NO_STATE;
					$this->yy_mark_start();
					$yy_this_accept = self::$yy_acpt[$yy_state];
					if (self::YY_NOT_ACCEPT != $yy_this_accept) {
						$yy_last_accept_state = $yy_state;
						$this->yy_mark_end();
					}
				}
			}
		}
	}
}
